﻿using System;
using System.IO;
using System.Runtime.Serialization;
using System.Text;
using System.Xml;

namespace ElectronicCommerce.Framework.Serialization
{
    /// <summary>
    /// DataContract序列化。
    /// http://blog.csdn.net/tmxk2002/archive/2009/03/29/4033864.aspx
    /// http://www.cnblogs.com/zsi/archive/2005/04/12/136005.html
    /// </summary>
    public class DataContractSerializerWrapper : SerializerBase
    {
        #region [ Fields ]

        private static ISerializer serializer = new DataContractSerializerWrapper();

        #endregion

        #region [ Methods ]

        /// <summary>
        /// 当前实例。
        /// </summary>
        public static ISerializer GetInstance()
        {
            return serializer;
        }

        /// <summary>
        /// 把对象转换成二进制数据。
        /// </summary>
        /// <typeparam name="T">要转换成二进制数据对象的类型。</typeparam>
        /// <param name="obj">要转换成二进制数据的对象。</param>
        /// <param name="encoding">编码。</param>
        /// <param name="extraTypes">要序列化的其他对象类型的 Type 数组。</param>
        /// <returns>二进制数据。</returns>
        public override byte[] ToBinary(object obj, Encoding encoding, Type[] extraTypes)
        {
            if (obj == null)
            {
                return null;
            }

            byte[] bytes;
            using (MemoryStream stream = new MemoryStream())
            {
                DataContractSerializer serializer = new DataContractSerializer(obj.GetType(), extraTypes);
                using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream, encoding))
                {
                    serializer.WriteObject(writer, obj);
                    writer.Flush();
                    stream.Seek(0, 0);
                    bytes = stream.ToArray();
                }
            }

            return bytes;
        }

        /// <summary>
        /// 不支持此序列化格式。
        /// </summary>
        /// <param name="bytes">要转换成的对象类型。</param>
        /// <param name="extraTypes">要序列化的其他对象类型的 Type 数组。</param>
        /// <returns>对象。</returns>
        public override object FromBinary(byte[] bytes, Type[] extraTypes)
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// 把二进制数据反序列化成对象。
        /// </summary>
        /// <param name="type">要转换成的对象类型。(没有使用)</param>
        /// <param name="bytes">二进制数据</param>
        /// <param name="encoding">编码。</param>
        /// <param name="extraTypes">要序列化的其他对象类型的 Type 数组。</param>
        /// <returns>对象。</returns>
        public override object FromBinary(Type type, byte[] bytes, Encoding encoding, Type[] extraTypes)
        {
            object ret = null;
            if (bytes == null || bytes.Length <= 0)
            {
                return ret;
            }

            using (MemoryStream stream = new MemoryStream(bytes))
            {
                DataContractSerializer serializer = new DataContractSerializer(type, extraTypes);
                using (XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(stream, encoding, XmlDictionaryReaderQuotas.Max, null))
                {
                    ret = serializer.ReadObject(reader);
                }
            }

            return ret;
        }

        #endregion
    }
}
